﻿<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>磁性吸附拖拽——模仿桌面的对齐拖拽</title>

<!--autor: carriehuang | QQ:453555909 | 转载需注明原处-->
<head>
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        body{
        	position: relative;
        }
     	.box{
     		width: 100px;
     		height: 100px;
     		background-color: blue;
     		position: absolute;
     	

     	}
        .box2{
     		width: 100px;
     		height: 100px;
     		background-color: red;
     		position: absolute;
 
			
     	}
     	 .box3{
     		width: 100px;
     		height: 100px;
     		background-color: yellow;
     		position: absolute;
     			
     	}
    </style>
</head>
<body>
	尽量靠近边缘试试看，有惊喜！
<div class="box" id="j_box"></div>
<div class="box2" id="j_box2"></div>
<div class="box3" id="j_box3"></div>


<script type="text/javascript">
/* 实现原理
 * onmousedown 选择元素
 * onmousemove 移动元素
 * onmouseup   释放元素
 * 
 * 拖拽的时候如果有文字被选中，会产生问题 ，如何解决 ？
 * 		原因：当鼠标按下的时候，如果页面中有文字被选中，会触发浏览器默认拖拽行为。这个是onmousedown事件触发的，所以需要在onmousedown阻止默认行为 
 * 		解决：
 *          标准：return false
 *          ie：setCapture
 * 
 * setCapture：设置全局捕获，当我们给一个元素设置全局捕获，那么这个元素会监听后续发生的所有事件，当有事件发生的时候，就会被当前设置了全局捕获的元素所捕获
 * 			   ie：有，并且有效果
 * 			   ff：有，但是无效果
 * 			   chrom: 没有，会报错
 * 
 * 拖拽的如果是图片也有问题，解决方法同上，阻止掉浏览器默认的事件
 * */

    window.onload=function(){
        var oBox = document.getElementById("j_box");
        var oBox2 = document.getElementById("j_box2");
        var oBox3 = document.getElementById("j_box3");
        	drag(oBox);
        	drag(oBox2);
        	drag(oBox3);
        	
        	
	        function drag(obj){
	        	obj.onmousedown = function(ev){					
					var ev = ev || event;
					//先计算原来鼠标坐标到元素坐标的距离
					var disX = ev.clientX - obj.offsetLeft;
					var disY = ev.clientY - obj.offsetTop;
					
					//添加全局捕获，取消掉浏览器 默认行为 
					if(obj.setCapture){
						obj.setCapture();
					};
					document.onmousemove = function(ev){
						var ev = ev || event;
						//限制被拖拽的元素可拖拽的范围
						var L = ev.clientX - disX;
						var T = ev.clientY - disY;	
						
							//左边
							if(L<100){ //判断距离多少时开始吸附
								L = 0;
							}else if(L>document.documentElement.clientWidth - obj.offsetWidth){ //右边       可视区宽度-元素布局宽度
								L=document.documentElement.clientWidth - obj.offsetWidth;
							}
							//上边
							if(T<100){
								T = 50;
							}else if(T>document.documentElement.clientHeight - obj.offsetHeight){ //下边
								T=document.documentElement.clientHeight - obj.offsetHeight;
							}
						//计算移动后的元素的距离 
						obj.style.left = L+'px';
						obj.style.top = T+'px';
						//console.log(obj.style.left);
						
					}
					//抬起鼠标按键后，取消掉移动事件，让元素停止移动
					document.onmouseup = function(){
						document.onmousemove = document.onmouseup = null;
						//抬起瞬间释放全局捕获
						if(obj.releaseCapture){
							obj.releaseCapture();
						}
					}
					return false;
				}
	        }
			
		}
</script>
</body>

</html>
